package cn.itsource.user.service.impl;

import cn.itsource.basic.service.impl.BaseServiceImpl;
import cn.itsource.user.contants.UserContants;
import cn.itsource.user.contants.WxInfoContants;
import cn.itsource.user.domain.LoginInfo;
import cn.itsource.user.domain.User;
import cn.itsource.user.domain.WxUser;
import cn.itsource.user.mapper.LoginInfoMapper;
import cn.itsource.user.mapper.UserMapper;
import cn.itsource.user.mapper.WxUserMapper;
import cn.itsource.user.service.IWxUserService;
import cn.itsource.utils.AjaxResult;
import cn.itsource.utils.HttpUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class WxUserServiceImpl extends BaseServiceImpl<WxUser> implements IWxUserService {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private WxUserMapper wxUserMapper;
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LoginInfoMapper loginInfoMapper;

    @Override
    public AjaxResult login(Map<String, String> map) {
        //1.获取code
        String code = map.get("code");
        String url= WxInfoContants.GET_ACCESSTOKEN
                .replace("APPID",WxInfoContants.APPID)
                .replace("SECRET",WxInfoContants.SECRET)
                .replace("CODE",code);
        //2.获取openid，access_token
        String wxResult = HttpUtils.sendGet(url);
        /*{ "access_token":"48_9XwYjQAzVkJrkqNdvXgjq7l9qo28eSWKjYPbhqdJ3FG2Q3UKE1wqsucTKgjU6L4LXWKpAQHI0CwOT8mKUkfbsJKGvUQFErsKcRFtj0dKXZc",
            "expires_in":7200,
            "refresh_token":"48_pLJJZrw8SwENYnbMweNrIjhsz-T--COZXBj-NZffTu9YQSSWQtZ5zVktNcGh8gkxfjAdioBIAHJ0Y4BHQd9An0chk-BsHddtIPEhnnA7CuY",
            "openid":"oa9wA07JrK9BDv6RSYTEsweUrgfs",
            "scope":"snsapi_login",
            "unionid":"ovnCWwzJ1NOT6zBTZLTuKGF_xS1o"
           }
        */
        System.out.println(wxResult);
        //2.1 转换json 获取里面指定的数据
        JSONObject jo = JSON.parseObject(wxResult);
        String openid = jo.getString("openid");
        String access_token = jo.getString("access_token");
        //3.检查用户是否第一次使用微信登录【t_wxuser 里面是否有用户的额openid】
        WxUser wxUser =wxUserMapper.loadByOpenId(openid);
        //老用户，不是第一次使用微信登录
        if (wxUser!=null&& wxUser.getUser()!=null){
            //免密登录
            LoginInfo loginInfo = loginInfoMapper.loadByUid(wxUser.getUser().getId());
            return noPwdLogin(loginInfo);
        }else {//新用户---跳转到绑定页面
            return new AjaxResult("/bindwechart.html?openid="+openid+"&access_token="+access_token);
        }

    }

    /*
         {
                phone: "",
                code: "",
                openId: ""
                access_token:""
			}

     */
    //绑定逻辑
    @Override
    @Transactional
    public AjaxResult bind(Map<String, String> map) {
        String phone = map.get("phone");
        String code = map.get("code");
        String openId = map.get("openId");
        String access_token = map.get("access_token");

        //1.校验验证码是否正确
        String codeAndTimeInRedis =(String)redisTemplate.opsForValue().get(UserContants.BIND_CODE+":"+phone);
        String codeInredis = codeAndTimeInRedis.split(":")[0];
        if (!codeInredis.equals(code)){
            return new AjaxResult("验证码错误，请重新输入");
        }
        //2.用户的输入的手机号是否注册过
        User user = userMapper.loadByPhone(phone);
        LoginInfo loginInfo=null;
        if (user==null){//没有注册过的用户
            //生成一个用户
            user=new User();
            user.setPhone(phone);
            user.setState(1);
            user.setUsername("u_"+phone);
            //生成用户放到数据库里面
            userMapper.save(user);
            //生成登录信息
            loginInfo = user2LoginInfo(user);
            loginInfoMapper.save(loginInfo);
        }
        //3.获取微信的个人信息，生成wxUser，并且关联User
        String url=WxInfoContants.GET_USERINFO
                .replace("ACCESS_TOKEN",access_token)
                .replace("OPENID",openId);
        String wxInfoResult = HttpUtils.sendGet(url);
        /*
            {
            "openid":"oa9wA0wUPEjuYV3pFIsaSeTq8Q0o",
            "nickname":"å·ê«",
            "sex":1,
            "language":"zh_CN",
            "city":"Chengdu",
            "province":"Sichuan",
            "country":"CN",
            "headimgurl":"https:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/c8s3YZTcniaFVichTQ7wb7MOicZvGwpAZ3tldsgSZwcSiaUiaOU89sZicMKMIzickRb8xia2CoffGx58zVvoIHtDX1OnGQ\/132",
            "privilege":[],"unionid":"ovnCWw04QjPFSJSyIlA9DVXuafRc"}


         */
        System.out.println(wxInfoResult);
        JSONObject jo = JSON.parseObject(wxInfoResult);
        WxUser wxUser = new WxUser();
        wxUser.setOpenid(jo.getString("openid"));
        wxUser.setNickname(jo.getString("nickname"));
        wxUser.setSex(jo.getInteger("sex"));
        wxUser.setHeadimgurl(jo.getString("headimgurl"));
        wxUser.setUnionid(jo.getString("unionid"));
        wxUser.setAddress(jo.getString("country")+jo.getString("province")+jo.getString("city"));
        wxUser.setUser(user);

        wxUserMapper.save(wxUser);

        //如果老用户 找到对应的loginInfo
        if (loginInfo==null){
            loginInfo =loginInfoMapper.loadByUid(user.getId());
        }
        //免密登录
        return noPwdLogin(loginInfo);
    }

    private LoginInfo user2LoginInfo(User user) {
        LoginInfo info = new LoginInfo();
        //数据的拷贝
        BeanUtils.copyProperties(user,info);
        //单独处理不能拷贝的字段
        info.setDisable(1);
        info.setType(1);
        info.setUId(user.getId());
        return info;
    }

    private AjaxResult noPwdLogin(LoginInfo loginInfo){
        String token = UUID.randomUUID().toString();
        //把当前的登录用户放到session里面
        redisTemplate.opsForValue().set(token,loginInfo,
                30, TimeUnit.MINUTES);

        Map<String,Object>map =new HashMap<>();
        //携带token
        map.put("token",token);
        //清空敏感数据
        loginInfo.setPassword("");
        loginInfo.setSalt("");
        map.put("loginInfo",loginInfo);
        return AjaxResult.me().setResultObj(map);
    }

}
